package entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

/**
 * Rappresenta un desiderio espresso da un utente.
 * I desideri sono personali dell'utente cosicch&eacute pi&ugrave
 * utenti possano condividere lo stesso oggetto (Item) desiderato.
 *
 * @see {@link entity.Item}
 * @author Rachid Ouchary, Fabio Strocco, Max Passaghe, Marco Tansini.
 */
@Entity
@Table(uniqueConstraints={@UniqueConstraint(columnNames={"item", "utente"})})
@NamedQueries({
@NamedQuery(name=Wish.FIND_WISH, query="SELECT w "
                                 + "FROM Wish w "
                                 + "WHERE w.item = :item "
                                 + "AND w.utente = :utente")
})
public class Wish implements Serializable {
    public static final String FIND_WISH = "findWishByValue";

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(nullable=false)
    private Integer priority;
    @Column(nullable=false)
    private Integer voto;
    @Column(nullable=false)
    private Boolean prenotato = false;
    @OneToOne
    @JoinColumn(nullable=false)
    private Item item;
    @ManyToOne
    private Utente utente;

    /**
     * Crea un nuovo desiderio.
     */
    public Wish() {
    }

    /**
     * Crea un nuovo desiderio.
     * @param priority la priorit&agrave data al desiderio, ossia quanto &egrave
     * urgente ottenere l'oggetto desiderato.
     * @param voto il voto del desiderio, ossia l'indicatore di
     * quanto l'utente ritiene utile l'oggetto desiderato.
     * @param item l'oggetto desiderato.
     */
    public Wish(Integer priority, Integer voto, Item item) {
        this.priority = priority;
        this.voto = voto;
        this.item = item;
    }

    /**
     * Restituisce l'utente a cui appartiene il desiderio.
     *
     * @return l'utente a cui appartiene il desiderio.
     */
    public Utente getUtente() {
        return utente;
    }

    /**
     * Imposta l'utente a cui appartiene il desiderio.
     *
     * @param utente l'utente a cui appartiene il desiderio.
     */
    public void attachUtente(Utente utente) {
        this.utente = utente;
    }

    /**
     * Restituisce l'oggetto a cui fa riferimento il desiderio.
     *
     * @return l'oggetto a cui fa riferimento il desiderio.
     */
    public Item getItem() {
        return item;
    }

    /**
     * Imposta l'oggetto desiderato.
     *
     * @param item l'oggetto desiderato.
     */
    public void setItem(Item item) {
        this.item = item;
    }

    /**
     * Restituisce la votazione data al desiderio, ossia l'indicatore di
     * quanto l'utente ritiene utile l'oggetto desiderato.
     *
     * @return il voto del desiderio.
     */
    public Integer getVoto() {
        return voto;
    }

    /**
     * Imposta il voto del desiderio, ossia l'indicatore di
     * quanto l'utente ritiene utile l'oggetto desiderato.
     *
     * @param voto il voto del desiderio.
     */
    public void setVoto(Integer voto) {
        this.voto = voto;
    }


    /**
     * Restituisce la priorit&agrave data al desiderio, ossia quanto &egrave
     * urgente ottenere l'oggetto desiderato.
     *
     * @return la priorit&agrave del desiderio.
     */
    public Integer getPriority() {
        return priority;
    }

    /**
     * Imposta la priorit&agrave data al desiderio, ossia quanto &egrave
     * urgente ottenere l'oggetto desiderato.
     *
     * @param priority la priorit&agrave del desiderios
     */
    public void setPriority(Integer priority) {
        this.priority = priority;
    }


    /**
     * Restituisce l'identificatore del desiderio.
     *
     * @return l'identificatore del desiderio.
     */
    public Long getId() {
        return id;
    }

    /**
     * Imposta il valore dell'id del desiderio.
     *
     * @param id il valore dell'id.
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * Indica se questo desiderio &egrave stato prenotato da qualcuno.
     *
     * @return <code>true</code> se il desiderio &egrave gi&agrave stato
     * prenotato, <code>false</code> altrimenti.
     */
    public boolean isPrenotato() {
        return prenotato;
    }

    public void prenota() {
        prenotato = true;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Wish)) {
            return false;
        }
        Wish other = (Wish) object;

        return (this.priority.equals(other.priority) &&
               (this.voto.equals(other.voto)) &&
               (this.prenotato.equals(other.prenotato)) &&
               (this.item.equals(other.item)) &&
               (this.utente.equals(other.utente)));
    }

    @Override
    public String toString() {
        return "entity.Wish[id=" + id + ", priority=" + priority +
                ", voto=" + voto + ", prenotato=" + prenotato +
                ", item=" + item + ", utente=" + (utente == null ? "NULL" : utente.getUsername()) + "]";
    }

    //<editor-fold defaultstate="collapsed" desc="Metodi deprecati">
    /**
     * Questo metodo serve solo per il WebService e pertanto
     * non dovrebbe essere utilizzato in quanto questo campo dovrebbe essere
     * controllato dal metodo prenota().
     * @deprecated 
     */
    public void setPrenotato(Boolean prenotato) {
        this.prenotato = prenotato;
    }

    /**
     * Questo metodo serve solo per il WebService e pertanto
     * non dovrebbe essere utilizzato in quanto questo campo non dovrebbe
     * essere letto in questo modo.
     * @deprecated
     */
    public Boolean getPrenotato() {
        return prenotato;
    }
    //</editor-fold>
}
